package com.sx.dao.daoImpl;

import com.sx.dao.SaleBillDao;
import com.sx.pojo.SaleBill;
import com.sx.utils.DatabaseUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.sql.*;
import java.util.ArrayList;

//销售记录
public class SaleBillDaoImpl implements SaleBillDao {
    //日志记录器
    private final Logger logger = LogManager.getLogger(SaleBillDaoImpl.class);

    /**
     * 获取所有销售记录
     * <p>
     * 此方法连接数据库，查询saleBill表中的所有记录，并将它们封装到SaleBill对象中，最后以ArrayList的形式返回
     *
     * @return 包含所有销售记录的ArrayList，如果查询失败或没有记录，则返回空列表
     */
    @Override
    public ArrayList<SaleBill> getAllSaleBill() {
        //创建数据库连接
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        SaleBill saleBill;
        ArrayList<SaleBill> saleBillList = new ArrayList<>();
        try {
            //获取数据库连接
            connection = DatabaseUtil.getConnection();
            if (connection != null) {
                //准备SQL查询
                String sql = "select * from saleBill";
                statement = connection.prepareStatement(sql);
                //执行查询并获取结果集
                resultSet = statement.executeQuery();
                //遍历结果集，将每条记录转换为SaleBill对象，并添加到列表中
                while (resultSet.next()) {
                    saleBill = new SaleBill();
                    saleBill.setSaleBillID(resultSet.getString("SaleBillID"));
                    saleBill.setGoods_id(resultSet.getString("Goods_id"));
                    saleBill.setGoods_name(resultSet.getString("Goods_name"));
                    saleBill.setSale_Date(resultSet.getDate("Sale_Date"));
                    saleBill.setNumber(resultSet.getInt("number"));
                    saleBill.setPerson_id(resultSet.getInt("Person_id"));
                    saleBill.setPerson_name(resultSet.getString("Person_name"));
                    saleBillList.add(saleBill);
                }
            } else {
                System.out.println("连接失败");
            }
        } catch (Exception e) {
            logger.error("获取销售记录失败", e);
        } finally {
            //关闭资源，释放系统资源
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (Exception e) {
                logger.error("关闭资源异常", e);
            }
        }
        //记录查询结果的日志
        logger.info("查询到销售记录数量：{}", saleBillList.size());
        logger.info("查询到销售记录信息：{}", saleBillList);
        return saleBillList;
    }

    /**
     * 检查销售单ID是否已存在于数据库中
     * 此方法用于防止重复的销售单ID，确保数据的唯一性和完整性
     *
     * @param saleBillID 销售单ID，用于查询数据库中是否存在重复的销售单
     * @return 如果存在重复的销售单ID，则返回true；否则返回false
     */
    @Override
    public boolean checkSaleBillIDExists(String saleBillID) {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            // 获取数据库连接
            conn = DatabaseUtil.getConnection();
            if (conn != null) {
                // SQL查询，检查销售单ID是否已存在
                String sql = "SELECT COUNT(*) FROM saleBill WHERE SaleBillID = ?";
                stmt = conn.prepareStatement(sql);
                stmt.setString(1, saleBillID);
                rs = stmt.executeQuery();
                if (rs.next()) {
                    // 日志记录销售单ID存在的情况
                    logger.info("销售记录ID存在：{}", saleBillID);
                    int count = rs.getInt(1);
                    // 如果查询结果大于0，表示销售单ID已存在
                    return count > 0;
                }
            } else {
                // 日志记录数据库连接失败的情况
                logger.error("连接失败");
            }
        } catch (Exception e) {
            // 日志记录数据库操作异常情况
            logger.error("数据库操作异常", e);
        } finally {
            // 关闭数据库资源，确保资源泄露不会发生
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (Exception e) {
                // 日志记录关闭资源时的异常情况
                logger.error("关闭资源异常", e);
            }
        }
        // 默认返回值，表示销售单ID不存在
        return false;
    }

    /**
     * 保存销售单信息到数据库
     *
     * @param saleBill 待保存的销售单对象
     * @return 返回保存是否成功，true表示成功，false表示失败
     */
    @Override
    public boolean saveSaleBill(SaleBill saleBill) {
        Connection conn = null;
        PreparedStatement stmt = null;
        try {
            // 获取数据库连接
            conn = DatabaseUtil.getConnection();
            if (conn != null) {
                // SQL插入语句，用于保存销售单信息
                String sql = "INSERT INTO saleBill (SaleBillID, Goods_id, Goods_name, Sale_Date, number, Person_id, Person_name) VALUES (?, ?, ?, ?, ?, ?, ?)";
                stmt = conn.prepareStatement(sql);
                // 设置SQL语句中的参数值
                stmt.setString(1, saleBill.getSaleBillID());
                stmt.setString(2, saleBill.getGoods_id());
                stmt.setString(3, saleBill.getGoods_name());
                stmt.setDate(4, (Date) saleBill.getSale_Date());
                stmt.setInt(5, saleBill.getNumber());
                stmt.setInt(6, saleBill.getPerson_id());
                stmt.setString(7, saleBill.getPerson_name());
                // 记录日志信息，执行插入操作
                logger.info("执行插入操作，并根据执行结果返回布尔值");
                return stmt.executeUpdate() > 0;
            } else {
                // 如果数据库连接失败，记录错误日志
                logger.error("连接失败");
            }
        } catch (Exception e) {
            // 如果数据库操作出现异常，记录错误日志
            logger.error("数据库操作异常", e);
        } finally {
            try {
                // 关闭数据库资源
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (Exception e) {
                // 如果关闭数据库资源时出现异常，记录错误日志
                logger.error("关闭资源异常", e);
            }
        }
        return false;
    }

    /**
     * 根据销售账单ID删除销售账单
     * 此方法尝试连接数据库并执行删除操作
     * 如果连接成功且删除操作影响的行数大于0，则返回true，表示删除成功
     * 否则，返回false，表示删除失败或未找到对应的销售账单
     *
     * @param saleBillID 销售账单的唯一标识符
     * @return 如果删除成功则返回true，否则返回false
     */
    @Override
    public boolean deleteSaleBillById(String saleBillID) {
        Connection conn = null;
        PreparedStatement stmt = null;
        logger.info("要删除的销售id：{}", saleBillID);
        try {
            // 获取数据库连接
            conn = DatabaseUtil.getConnection();
            if (conn != null) {
                // 准备SQL语句，用于删除指定ID的销售账单
                String sql = "DELETE FROM saleBill WHERE SaleBillID = ?";
                stmt = conn.prepareStatement(sql);
                stmt.setString(1, saleBillID);
                // 执行删除操作，并根据执行结果返回布尔值
                logger.info("执行删除操作，并根据执行结果返回布尔值");
                return stmt.executeUpdate() > 0;
            } else {
                // 如果连接失败，记录错误日志
                logger.error("连接失败");
            }
        } catch (Exception e) {
            // 数据库操作异常时，记录错误日志
            logger.error("数据库操作异常", e);
        } finally {
            try {
                // 关闭数据库资源
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                // 关闭资源时发生异常，记录错误日志
                logger.error("关闭资源异常", e);
            }
        }
        // 默认返回值，表示删除操作失败
        return false;
    }

    /**
     * 根据销售账单ID获取销售账单信息
     * 此方法通过数据库查询来获取与给定销售账单ID匹配的账单信息，并将其封装为SaleBill对象返回
     * 如果没有找到匹配的账单，或者数据库连接失败，或者查询过程中发生异常，则返回null
     *
     * @param saleBillID 销售账单的唯一标识符
     * @return SaleBill对象，包含账单的详细信息，如果没有找到则返回null
     */
    @Override
    public SaleBill getSaleBillById(String saleBillID) {
        Connection conn = null;
        PreparedStatement stmt = null;
        try {
            // 获取数据库连接
            conn = DatabaseUtil.getConnection();
            if (conn != null) {
                // 准备SQL查询
                String sql = "SELECT * FROM saleBill WHERE SaleBillID = ?";
                stmt = conn.prepareStatement(sql);
                stmt.setString(1, saleBillID);
                // 执行查询
                ResultSet rs = stmt.executeQuery();
                // 处理查询结果
                if (rs.next()) {
                    String Goods_id = rs.getString("Goods_id");
                    String Goods_name = rs.getString("Goods_name");
                    Date Sale_Date = rs.getDate("Sale_Date");
                    int number = rs.getInt("number");
                    int Person_id = rs.getInt("Person_id");
                    String Person_name = rs.getString("Person_name");
                    // 日志记录查询成功的账单ID
                    logger.info("查询到销售账单：{}", saleBillID);
                    // 创建并返回SaleBill对象
                    return new SaleBill(saleBillID, Goods_id, Goods_name, Sale_Date, number, Person_id, Person_name);
                }
            } else {
                // 日志记录连接失败
                logger.error("连接失败");
            }
        } catch (Exception e) {
            // 日志记录数据库操作异常
            logger.error("数据库操作异常", e);
        } finally {
            // 关闭数据库资源
            try {
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                // 日志记录关闭资源异常
                logger.error("关闭资源异常", e);
            }
        }
        // 如果没有找到账单或发生异常，返回null
        return null;
    }

    /**
     * 更新销售单信息
     * 此方法用于更新数据库中的销售单记录，包括商品ID、商品名称、销售日期、数量、人员ID和人员名称
     *
     * @param saleBill 待更新的销售单对象，包含需要更新的销售单的所有信息
     * @return boolean 表示更新操作是否成功，如果成功则返回true，否则返回false
     */
    @Override
    public boolean updateSaleBill(SaleBill saleBill) {
        Connection conn = null;
        PreparedStatement stmt = null;
        try {
            // 获取数据库连接
            conn = DatabaseUtil.getConnection();
            if (conn != null) {
                // 定义更新SQL语句
                String sql = "UPDATE saleBill SET Goods_id = ?, Goods_name = ?, Sale_Date = ?, number = ?, Person_id = ?, Person_name = ? WHERE SaleBillID = ?";
                // 预编译SQL语句
                stmt = conn.prepareStatement(sql);
                // 设置SQL语句中的参数值
                stmt.setString(1, saleBill.getGoods_id());
                stmt.setString(2, saleBill.getGoods_name());
                stmt.setDate(3, new java.sql.Date(saleBill.getSale_Date().getTime()));
                stmt.setInt(4, saleBill.getNumber());
                stmt.setInt(5, saleBill.getPerson_id());
                stmt.setString(6, saleBill.getPerson_name());
                stmt.setString(7, saleBill.getSaleBillID());
                // 记录日志信息
                logger.info("设置SQL语句中的参数值:{}", saleBill);
                // 执行更新操作并返回结果
                return stmt.executeUpdate() > 0;
            } else {
                // 如果连接失败，记录错误日志
                logger.error("连接失败");
            }
        } catch (Exception e) {
            // 记录数据库操作异常日志
            logger.error("数据库操作异常", e);
        } finally {
            // 关闭资源
            try {
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                // 记录关闭资源异常日志
                logger.error("关闭资源异常", e);
            }
        }
        // 如果更新操作失败，返回false
        return false;
    }
}

